# 基于G6.js封装拓扑图插件

随着业务的迅速发展,以前控制器中使用D3.js实现的拓扑图功能渐渐地不能满足需求:

  1. 代码组织混乱,各功能未有序解耦,维护困难。
  2. 未插件化,不能供多个项目使用。
  3. D3.js使用svg来实现,在数据量大时需要生成数量庞大的dom结构。

因此,拓扑图急需一次大的升级。

# 插件选型

市面上有不少拓扑图插件,例如:

# 1. AntV G6

简介:G6 是一个图可视化引擎。它提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。 背景:蚂蚁金服 AntV、国产 官网:https://antv.vision/zh 示例:https://github.com/wenyuan/cceditor

  • 优点
    • 开源免费
    • 上手简单,可扩展性强
    • 功能丰富,支持各种自定义操作
    • 由蚂蚁金服 AntV 团队开发,从维护性和生态圈角度考虑相对有保障
    • 支持自动布局(早期借助 d3-force 实现,后期已经被内部支持)
  • 缺点
    • 有时候文档和版本会脱节(可以理解,问题不大)
  • 建议
    • 大厂团队开发维护,后期有保障,大小项目都可以使用
    • 可以学习里面的一些编程思想和技巧

# 2. D3

只提供画图能力,画什么需要自己实现。

# 3. ECharts

简介:ECharts 关系图。 背景:百度、国产 官网:https://www.echartsjs.com/zh/index.html

  • 优点
    • 上手非常简单
    • 文档齐全
  • 缺点
    • 扩展性弱(毕竟不是专做图编辑器的,关系图只是 ECharts 中的一项)
  • 建议
    • 可以用在定制化的需求中,不需要拖拉拽等功能

# 选型总结

除了上面提到的,还有一些国内外个人开发的插件,但普遍存在维护无保障、文档不齐全等问题。

另外D3之前就在用,存在的问题上面也讲过了。

Echarts拓展性不强,无法适应多变的需求。

加上深信服已经有基于G6.js封装了插件,可以在其基础上快速实现功能,于是最终选定使用G6进行开发。

# 功能实现

# 目录

└───docs // 文档
└───example // 示例
└───src
│   └───assets // 图片资源
│   └───behavior // 行为方法
│   └───config // 公共配置
│   └───controller // 注册类型
│   └───core // 插件核心代码
│   └───event // 事件
│   └───extends // 扩展G6
│   └───language // 国际化
│   └───layout // 布局
│   └───plugin // 插件
│   └───shapes // 自定义类型
│   └───style // 样式
│   └───utils // 公共方法
│   index.js

# 架构图

# 数据转换

各项目的数据格式肯定是不一致的,插件为了兼容各种数据格式,对外暴露了转换数据的方法,用户可自定义转换数据格式,将数据转成G6的格式。

# 布局

# 树形交叉布局

项目的树形需求主要有几个难点:

  1. 需要不同父集的子集间能相互连接(交叉连线)
  2. 存在不在树结构里的元素
  3. 存在分支拓扑,即树拓扑中存在子树拓扑

G6原生支持的树形拓扑十分死板,只能展示单纯的树形结构。

# 实现

本插件通过扩展dagre布局,并实现展开收起功能,完美实现需求。

# 保持顺序

为了保持同层级节点的排列顺序,自动将每层中最多子节点的节点放在中间(为了美观),其余按数据传入的顺序进行排序。

# 展开收起

展开收起子节点,会自动更新节点的位置,达到类似xmind的伸缩位置的效果。

# 自定义图形、事件

插件内置了各种图形、事件。

# 连线

扩展了三阶贝塞尔曲线,可根据传入的数据,显示传输速率、繁忙度、连接方式等信息。

# 网络设备

内置了控制器、接入点、盒式交换机、框式交换机等设备类型,用户可直接使用,需要额外自定义的设备类型可通过配置化的方式传入,插件会自动注册成G6的自定义类型。

内置了多套尺寸的样式,随着缩放比例的变化自动切换显示。

# 事件系统

内置了一系列事件,统一在图实例发送接收,方便外部使用。

# 内置svg

内置了一系列设备图片,可像在vue中使用svg组件一样使用。

# 差量更新

针对周期性自动更新数据的场景,提供了差量对比、更新的功能。

# 坐标处理

# 全新

所有节点都没坐标,或者更新时配置了去计算坐标时,会走配置的layout的布局算法去计算位置。

如果感到计算速度缓慢,可以开启webwork功能进行加速。

# 有新有旧

有坐标的节点使用旧坐标,无坐标的走布局算法。

# 全旧

全部都有坐标,则直接使用旧坐标,不走布局算法,节省性能。

# 文档

一个大型的项目,不能缺少了使用文档。

这里使用VuePress作为静态网站生成器,可快速实现预览编写的.md格式文档。

# 国际化

可在初始化拓扑图时,传入语言类型来控制文字显示。

内置了国际化方案,同时可接收使用外部的翻译转换逻辑。

# 开发体验

# mock数据

可配置化的生成指定层级、数量的假数据,方便测试及展示。

# 自定义console

可自定义console打印的样式,等级。

可方便的控制打印时机。

# 打印执行用时

在关键函数调用处,都添加了执行计时,可方便的看出性能瓶颈。

# 拓展G6.js

G6.js的原型方法进行拓展、补充。

# behavior

# brush-select

G6内置的框选操作,是不支持在combo内部去拖动的。

插件通过重写该行为,实现在combo中进行框选。

# drag-canvas

拖动画布的操作。

在大数据量时,拖动画布及其卡顿,这里借鉴了vuenextTick的原理,将更新汇总,一段时间只执行一次,达到优化性能的目的。

# zoom-canvas

滚轮进行缩放时,有时会到不了给定的最大最小缩放值。

插件这里判断达到极值时,直接使用该值,从而解决该bug。

# minimap

G6有提供两种缩略图,minimapimageMinimap

区别就是minimap是根据graph再用canvas画一次,而imageminimap是将我们自己给的图片显示出来(但是需要自己监听变化并给出图片)。

可想而知,在大量数据的情况下,双倍渲染canvas肯定消耗更大的性能。

本插件通过修改imageminimap,实现了自动监听graph变化,同时生成图片并渲染到缩略图上。

# 打包

使用webpack5进行打包

# 开发环境

已内置两套开发环境(普通html和vue)。

通过npm run dev即可启动开发环境,自动监听样例代码和拓扑图插件代码变化,热更新页面。

# 生产环境

提供umdesm两种格式,方便使用。

# 新手指引

封装了新手指引功能,可让用户快速上手功能。

# 插件系统

所有插件均配置化,可传入配置进行启用、重写。

# 数据工具栏

# 刷新

自定义数据刷新时间。

# 选取方式

切换单选和框选模式。

# 对齐

类似于思维导图中的对齐功能,可对选中的节点进行水平、垂直、左、右等等对齐方式。

# 撤销

即上一步,支持无限步。

# 导出

将拓扑图以图片形式导出。

# 大数据量优化

插件针对大数据场景做了优化,G6直出的图片在大数据时会导出失败(浏览器对canvas的最大尺寸的限制),所以我们对数据采用分批导出。

# 清晰度

G6直出的图片清晰度不是很好,插件通过动态改变像素比来放大尺寸,从而提高清晰度。

# 显示设置

节点上的某些元素可通过配置去控制显示。

# 快速展开收起

可对节点快速的全部展开、全部收起、按层展开、按层收起。

# 视图

可保存多份坐标、显示、缩放等展示信息的视图,让用户可以快速切换到想看的设备处。

# 搜索

通过关键字搜索并高亮相关数据。

# 可配置

可配置需要搜索的字段

# 高亮

对搜索到的节点进行高亮显示。

同时,如果节点是被收起的状态,会自动打开其父级combo。

# 视图工具栏

对图进行放大、缩小、自适应缩放、缩略图、全屏等操作。

# tooltip

鼠标悬浮提示

# 背景

可配置画布的背景颜色、图片等。

# 右键菜单

可配置右键元素时显示菜单。

# 命令系统

操作动作都写入命令系统,在dom元素上添加命令名即可实现动作。

并可配置命令快捷键。

# 图例

设备图片示例,可动态传入数据进行显示。

# 自动注册类型

图例自然包含所有的类型,所以当开启图例时,会自动根据配置项去注册节点类型。

# 筛选

可通过点击类型去筛选数据。

可与搜索功能组合进行筛选。

# loading

画布未渲染完成时,可配置显示loading动画。

# 对齐辅助线

G6snapLine插件只有显示辅助线的功能。

插件对其进行扩展,添加了移动到附近节点时会进行吸附对齐的功能。

# 扩展性

插件、设备样式等均已配置化,可传入数据进行重写,十分方便的完成换肤、拓展等自定义需求。

# 兼容性

现代浏览器完美兼容。

ie10环境,内部使用polyfill兼容。